package com.example.matchingengine.service.strategy;

import com.example.matchingengine.model.Order;
import com.example.matchingengine.model.Order.OrderStatus;
import com.example.matchingengine.service.event.TradeEvent;
import com.example.matchingengine.service.model.OrderBook;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;

/**
 * 市价卖单匹配策略
 */
@Slf4j
public class MarketSellStrategy extends AbstractMatchingTemplate {
    
    @Override
    protected void doMatch(Order order, OrderBook orderBook) {
        matchMarketSellOrder(order, orderBook);
    }
    
    @Override
    public String getStrategyType() {
        return "MARKET_SELL";
    }
    
    /**
     * 撮合市价卖单
     * 市价卖单会以当前最优买价立即成交，直到卖单完全成交或买盘无订单
     */
    private void matchMarketSellOrder(Order marketSellOrder, OrderBook orderBook) {
        log.info("开始撮合市价卖单: {}, 数量: {}", marketSellOrder.getId(), marketSellOrder.getQuantity());
        
        boolean fullyMatched = false;
        boolean hasMatched = false; // 标记是否有成交

        // 循环匹配买盘订单，市价单需要立即成交
        while (!orderBook.getBuyOrders().isEmpty() && !fullyMatched) {
            // 获取买盘最高价格
            BigDecimal highestBuyPrice = orderBook.getBuyOrders().firstKey();

            // 获取该价格下的订单列表
            LinkedList<Order> ordersAtPrice = orderBook.getBuyOrders().get(highestBuyPrice);
            if (ordersAtPrice.isEmpty()) {
                orderBook.getBuyOrders().remove(highestBuyPrice);
                continue;
            }

            // 获取该价格下最早的订单（时间优先）
            Order buyOrder = ordersAtPrice.getFirst();

            // 计算可成交数量
            BigDecimal remainingSellQty = marketSellOrder.getQuantity().subtract(marketSellOrder.getFilledQuantity());
            BigDecimal remainingBuyQty = buyOrder.getQuantity().subtract(buyOrder.getFilledQuantity());
            BigDecimal matchQty = remainingSellQty.min(remainingBuyQty);

            // 更新订单成交数量
            marketSellOrder.setFilledQuantity(marketSellOrder.getFilledQuantity().add(matchQty));
            buyOrder.setFilledQuantity(buyOrder.getFilledQuantity().add(matchQty));
            hasMatched = true; // 标记有成交

            // 生成成交事件，市价卖单以买单价格成交
            TradeEvent tradeEvent = new TradeEvent(
                    buyOrder.getId(),
                    marketSellOrder.getId(),
                    orderBook.getSymbol(),
                    buyOrder.getPrice(), // 市价卖单以买单价格成交
                    matchQty,
                    LocalDateTime.now()
            );

            // 发送成交消息到RocketMQ
            orderBook.sendTradeEvent(tradeEvent);

            // 记录成交计数
            orderBook.incrementTradeCounter();

            // 检查买单是否完全成交
            if (buyOrder.getFilledQuantity().compareTo(buyOrder.getQuantity()) >= 0) {
                // 从买盘移除已完全成交的订单
                Order removedOrder = ordersAtPrice.removeFirst();
                // 从订单映射表中移除
                orderBook.getOrderMap().remove(removedOrder.getId());
                if (ordersAtPrice.isEmpty()) {
                    orderBook.getBuyOrders().remove(highestBuyPrice);
                }
                buyOrder.setStatus(OrderStatus.FILLED);
                buyOrder.setUpdateTime(LocalDateTime.now());

                // 发送订单状态更新消息
                orderBook.sendOrderStatusUpdate(buyOrder);
            } else {
                // 部分成交
                buyOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
                buyOrder.setUpdateTime(LocalDateTime.now());

                // 发送订单状态更新消息
                orderBook.sendOrderStatusUpdate(buyOrder);
            }

            // 检查市价卖单是否完全成交
            if (marketSellOrder.getFilledQuantity().compareTo(marketSellOrder.getQuantity()) >= 0) {
                marketSellOrder.setStatus(OrderStatus.FILLED);
                fullyMatched = true;
                log.info("市价卖单完全成交: {}", marketSellOrder.getId());
            } else {
                marketSellOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
            }

            marketSellOrder.setUpdateTime(LocalDateTime.now());
        }

        // 市价单如果未完全成交，标记为部分成交（不加入订单簿）
        if (!fullyMatched) {
            log.warn("市价卖单未完全成交，剩余数量: {}, 订单ID: {}", 
                    marketSellOrder.getQuantity().subtract(marketSellOrder.getFilledQuantity()), 
                    marketSellOrder.getId());
            // 市价单不加入订单簿，设置最终状态
            if (marketSellOrder.getFilledQuantity().compareTo(BigDecimal.ZERO) > 0) {
                marketSellOrder.setStatus(OrderStatus.PARTIALLY_FILLED);
            } else {
                // 如果完全没有成交，标记为拒绝
                marketSellOrder.setStatus(OrderStatus.REJECTED);
                log.warn("市价卖单完全无法成交，标记为拒绝: {}", marketSellOrder.getId());
            }
        }

        // 市价单总是需要发送状态更新消息（包括REJECTED状态）
        // 但对于完全没有成交的情况，只有状态变为REJECTED时才发送
        if (hasMatched || marketSellOrder.getStatus() == OrderStatus.REJECTED) {
            orderBook.sendOrderStatusUpdate(marketSellOrder);
        }
    }
}